/**
 * 
 */
package kr.co.insoft.driver.openstack.process;

import static kr.co.insoft.driver.openstack.Contants.POLL_PERIOD_TWENTY_SECONDS;
import static org.jclouds.compute.config.ComputeServiceProperties.POLL_INITIAL_PERIOD;
import static org.jclouds.compute.config.ComputeServiceProperties.POLL_MAX_PERIOD;

import java.io.Closeable;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;

import kr.co.insoft.driver.exception.DriverException;
import kr.co.insoft.driver.exception.ExceptionCode;
import kr.co.insoft.driver.openstack.model.OpenStackCredentialModel;
import kr.co.insoft.driver.openstack.model.OpenStackInstanceModel;

import org.jclouds.ContextBuilder;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import com.google.common.collect.ImmutableSet;
import com.google.common.io.Closeables;
import com.google.inject.Module;

/**
 * RackSpace 서비스 중 서버 삭제 관련 Process
 * 
 * @author IN-SOFT Inc. skpark@in-soft.co.kr
 * 
 */
public class DeleteServerProcess implements Closeable {

	private static final Logger logger = LoggerFactory
			.getLogger(DeleteServerProcess.class);

	private final OpenStackCredentialModel credentialModel;
	private final ComputeService computeService;

	public DeleteServerProcess(OpenStackCredentialModel credentialModel)
			throws DriverException {
		this.credentialModel = credentialModel;

		try {
			Assert.notNull(this.credentialModel);
			Assert.notNull(this.credentialModel.getUsername());
			Assert.notNull(this.credentialModel.getAccessKey());
		} catch (IllegalArgumentException e) {
			if (logger.isDebugEnabled()) {
				logger.debug("credentialModel : {}", this.credentialModel);
			}
			throw new DriverException(ExceptionCode.ARGUMENT_ERROR, e);
		}

		try {
			Properties overrides = new Properties();
			overrides.setProperty(POLL_INITIAL_PERIOD,
					POLL_PERIOD_TWENTY_SECONDS);
			overrides.setProperty(POLL_MAX_PERIOD, POLL_PERIOD_TWENTY_SECONDS);
			
			Iterable<Module> modules = ImmutableSet
					.<Module> of(new SLF4JLoggingModule());

			ComputeServiceContext context = ContextBuilder
					.newBuilder(this.credentialModel.getProvider())
					.credentials(this.credentialModel.getUsername(),
							this.credentialModel.getAccessKey())
					.endpoint(this.credentialModel.getEndpoint())
					.modules(modules).overrides(overrides)
					.buildApi(ComputeServiceContext.class);
			computeService = context.getComputeService();
		} catch (Exception e) {
			throw new DriverException(ExceptionCode.DRIVER_ERROR, e);
		}
	}

	public Set<OpenStackInstanceModel> terminateServer(
			Collection<String> serverIds) throws DriverException {
		return terminateServer(serverIds.toArray(new String[] {}));
	}

	public Set<OpenStackInstanceModel> terminateServer(String... serverIds)
			throws DriverException {
		Set<OpenStackInstanceModel> result = new HashSet<OpenStackInstanceModel>();
		OpenStackInstanceModel instance = null;

		Set<? extends NodeMetadata> servers = null;
		for (String serverId : serverIds) {			
			String groupName = computeService.getNodeMetadata(serverId).getGroup();
			servers = computeService
					.destroyNodesMatching(org.jclouds.compute.predicates.NodePredicates
							.inGroup(groupName));
			Iterator<? extends NodeMetadata> iter = servers.iterator();
			while (iter.hasNext()) {
				instance = new OpenStackInstanceModel(
						(NodeMetadata) iter.next());
				result.add(instance);
			}
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.io.Closeable#close()
	 */
	@Override
	public void close() throws IOException {
		Closeables.close(computeService.getContext(), true);
	}

}
